﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
//using SkypeDialer.crm;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Sdk.Metadata;
using Microsoft.Crm.SdkTypeProxy.Metadata;

namespace SkypeDialer.Classes
{
    public class CrmDataAdapter : IDataAdapter
    {
        CrmService service;
        MetadataService metaservice;

        public CrmDataAdapter(string orgName, Uri currentUri)
        {
            // Connection to Crm web-service    
#if (!DEBUG)
            // TODO: переделать - брать урл сервисов из реестра
            string crmserviceUrl = GetCrmServiceUrlFromRegistry();
            string metaserviceUrl = GetMetadataServiceUrlFromRegistry();
#else
            string crmserviceUrl = string.Format("http://62.173.132.150:3006/mscrmservices/2007/crmservice.asmx", currentUri.Scheme, Uri.SchemeDelimiter, currentUri.Host, currentUri.Port);
            string metaserviceUrl = string.Format("http://62.173.132.150:3006/mscrmservices/2007/metadataservice.asmx", currentUri.Scheme, Uri.SchemeDelimiter, currentUri.Host, currentUri.Port);
#endif
            service = new CrmService();
            service.Url = crmserviceUrl;
            service.Credentials = System.Net.CredentialCache.DefaultCredentials;

            CrmAuthenticationToken token = new CrmAuthenticationToken();
            token.OrganizationName = orgName;

            service.CrmAuthenticationTokenValue = token;

            // Connection to CRM metadata service
            metaservice = new MetadataService();
            metaservice.Url = metaserviceUrl;
            metaservice.Credentials = System.Net.CredentialCache.DefaultCredentials;
            metaservice.CrmAuthenticationTokenValue = token;

        }

        #region IDataAdapter Members

        List<ContactInfo> IDataAdapter.GetContacts(string contactid, string entityname)
        {
            Guid id;

            try
            {
                id = new Guid(contactid);
            }
            catch(ArgumentException aex)
            {
                throw new ArgumentException("Не указан или указан неверно идентификатор объекта", aex);
            }

            // Получаем список телефонов
            return GetPhoneTable(entityname, id); 
            
        }


        private List<ContactInfo> GetPhoneTable(string typename, Guid id)
        {
            List<ContactInfo> ciList = new List<ContactInfo>();

            // Получаем конфигурацию
            Configuration.ICrmDataAdapterConfigurationProvider config = new Configuration.OutOfBoxCRMConfigurationProvider();

            // Получаем конфигурацию для нашей сущности
            Configuration.ContactInfoEntity cie = config.ContactInfoEntities[typename];

           

            // Получаем объект
            RetrieveRequest req = new RetrieveRequest();
            req.ColumnSet = new Microsoft.Crm.Sdk.Query.ColumnSet((from a in cie.ContactInfoAttributes
                                                                     select a.AttributeName).ToArray());
            req.ReturnDynamicEntities = true;
            TargetRetrieveDynamic target = new TargetRetrieveDynamic();
            target.EntityId = id;
            target.EntityName = typename;
            req.Target = target;


            RetrieveResponse resp = (RetrieveResponse)service.Execute(req);

            DynamicEntity o = (DynamicEntity)resp.BusinessEntity;


            foreach (Configuration.ContactInfoAttribute cia in cie.ContactInfoAttributes)
            {
                if (o.Properties.Contains(cia.AttributeName) && (string)o.Properties[cia.AttributeName] != string.Empty)
                    ciList.Add(new ContactInfo()
                    {
                        CallingId = (string)o.Properties[cia.AttributeName],
                        IsCallAvailable = cia.IsCallAvailable,
                        IsChatAvailable = cia.IsChatAvailable,
                        IsStatusAvailable = cia.IsStatusAvailable,
                        IsVideoCallAvailable = cia.IsVideoCallAvailable,
                        IsSMSAvailable = cia.IsSMSAvailable,
                        CallingIdName = GetAttributeDisplayName(typename, cia.AttributeName)
                    });

            }

            return ciList;
        }

        private string GetAttributeDisplayName(string entityname, string attributename)
        {
            RetrieveAttributeRequest req = new RetrieveAttributeRequest()
                {
                    EntityLogicalName = entityname,
                    LogicalName = attributename
                };

            RetrieveAttributeResponse resp = (RetrieveAttributeResponse)metaservice.Execute(req);

            return resp.AttributeMetadata.DisplayName.UserLocLabel.Label;
        }

        #endregion

        private static string GetServerUrlFromRegistry()
        {
            string str = (string)Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\MSCRM").GetValue("ServerUrl");
            if (!str.EndsWith("/"))
            {
                str = str + "/";
            }
            return str;
        }

        private static string GetCrmServiceUrlFromRegistry()
        {
            return (GetServerUrlFromRegistry() + "2007/CrmService.asmx");
        }

        private static string GetMetadataServiceUrlFromRegistry()
        {
            return (GetServerUrlFromRegistry() + "2007/MetadataService.asmx");
        }

    }
}